<template>
    <div class="controlPanel-box">
        <site-nav/>
        <div class="controlPanel-bg">
            <div class="basic-info">
                <user-my-avatar :enable-preview="false" size="80"/>
                <p>你好，{{info.departmentName}}的{{info.name}} <i>({{info.username}})</i>，你的上次登陆时间是：{{info.lastLoginTime |
                    dateFormat('YYYY-MM-DD HH:mm')}}</p>
            </div>

            <el-upload :action="getUploadAvatarUrl()" :headers="getHeaders()" :on-success="handleUploaded"
                       :show-file-list="false"
                       accept="image/*" class="avatar-button">
                <el-button class="upload-avatar-box" type="text">修改头像</el-button>
            </el-upload>
            <el-button @click="deleteAvatar()" class="avatar-button" type="text" v-if="!$isDefaultAvatar(info.avatar)">
                删除头像
            </el-button>
            <el-row>
                <div class="table-title">账户安全</div>
                <el-form label-width="100px">
                    <el-form-item label="安全程度">
                        <el-progress :percentage="securityProgress.value"
                                     :status="securityProgress.status"
                                     class="security-progress"
                        />
                        安全级别：{{securityProgress.displayText}}
                    </el-form-item>
                    <el-form-item label="账户密码">
                        安全性高的密码可以使帐号更安全。建议您定期更换密码。
                        <el-button @click="changePassword" type="warning">修改密码</el-button>
                    </el-form-item>
                    <el-form-item label="手机绑定">
                        <template v-if="info.phone">
                            您已绑定了手机{{formatPhone(info.phone)}}
                        </template>
                        <template v-else>
                            您尚未绑定手机
                        </template>
                    </el-form-item>
                    <el-form-item label="邮箱绑定">
                        <template v-if="info.email">
                            您已绑定了邮箱{{formatEmail(info.email)}}
                        </template>
                        <template v-else>
                            您尚未绑定邮箱
                        </template>
                    </el-form-item>
                    <el-form-item label="虚拟MFA">
                        <template v-if="info.enableTwoFactorAuthentication">
                            您已绑定了虚拟MFA，您可以在登录时通过它来进行二次校验或进行系统关键操作。
                            <el-button @click="disableTwoFactorAuthentication" type="danger">解绑</el-button>
                        </template>
                        <template v-else>
                            绑定虚拟MFA后，您可以在登录时通过它来进行二次校验或进行系统关键操作。
                            <el-button @click="getTwoFactorAuthenticationBindInfo" type="warning">绑定</el-button>
                        </template>
                    </el-form-item>
                    <el-form-item label="第三方账号">
                        <template v-for="bind in oauthBinds">
                            <el-tag :closable="bind.bound" :key="bind.key" :type="bind.bound ? '' : 'info'"
                                    @close="unBind(bind)"
                                    class="oauth" effect="plain">
                                {{bind.label}}
                            </el-tag>
                        </template>
                    </el-form-item>
                </el-form>
            </el-row>
            <el-row>
                <div class="table-title">所拥有的身份</div>
                <el-tag class="position" type="danger" v-isAdmin>系统管理员</el-tag>
                <el-tag :key="`${item.departmentId}_${item.dutyId}`" class="position" type="success"
                        v-for="(item) in list" v-if="item.dutyId === '1'">{{item.departmentName}} - {{item.dutyName}}
                </el-tag>
                <el-tag :key="`${item.departmentId}_${item.dutyId}`" class="position" type="warning"
                        v-for="(item) in list" v-if="item.dutyId === '2'">{{item.departmentName}} - {{item.dutyName}}
                </el-tag>
                <el-tag :key="`${item.departmentId}_${item.dutyId}`" class="position" v-for="(item) in list"
                        v-if="item.dutyId !== '1' && item.dutyId !== '2'">{{item.departmentName}} - {{item.dutyName}}
                </el-tag>
            </el-row>
        </div>

        <el-dialog :visible.sync="changePasswordDialog.show" @close="cancelChangePassword" class="dialog" title="修改密码">
            <el-form :model="password" label-width="100px">
                <el-form-item label="原密码" prop="oldPassword">
                    <el-input auto-complete="off" placeholder="原密码" type="password"
                              v-model="password.oldPassword"/>
                </el-form-item>
                <el-form-item label="新密码" prop="newPassword">
                    <el-input auto-complete="off" placeholder="新密码" type="password"
                              v-model="password.newPassword"/>
                </el-form-item>
            </el-form>
            <div class="dialog-footer" slot="footer">
                <el-button @click="cancelChangePassword">取 消</el-button>
                <el-button @click="submitChangePassword" type="primary">确 定</el-button>
            </div>
        </el-dialog>

        <el-dialog :before-close="cancelTwoFactorAuthentication" :visible.sync="otpDialog.show" class="dialog"
                   title="绑定MFA">
            <p class="tips">1。请先在您的手机上安装Microsoft Authenticator。</p>
            <div class="qrcode-box">
                <el-col :span="12">
                    <qrcode :size="160" :value="iphoneDownload" class="qrcode"/>
                    <span>iphone</span>
                </el-col>
                <el-col :span="12">
                    <qrcode :size="160" :value="androidDownload" class="qrcode"/>
                    <span>android</span>
                </el-col>
            </div>
            <p class="tips">2。扫描下方二维码添加账户信息。</p>
            <div class="qrcode-box">
                <qrcode :size="160" :value="qrBarcode" class="qrcode"/>
            </div>
            <p class="tips">3。输入动态密码，点击"确 定"按钮完成绑定。</p>
            <el-input :autofocus="true" maxlength="6" placeholder="请输入动态密码" type="text" v-model="otp"/>
            <div class="dialog-footer" slot="footer">
                <el-button @click="cancelTwoFactorAuthentication" size="mini">取 消</el-button>
                <el-button :loading="otpDialog.submitting" @click="enableTwoFactorAuthentication" size="mini"
                           type="primary">确 定
                </el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script lang="ts">
  import AbstractOauthControlPanelApi from '@/api/user/abstractOauthControlPanelApi';
  import ControlPanelApi from '@/api/user/controlPanelApi';
  import DingTalkControlPanelApi from '@/api/user/dingTalkControlPanelApi';
  import WxCpControlPanelApi from '@/api/user/wxCpControlPanelApi';
  import AvatarModule from '@/store/modules/avatar';
  import DialogInfo from '@/structure/dialogInfo';
  import PasswordInfo from '@/structure/passwordInfo';
  import Position from '@/structure/position';
  import Result from '@/structure/result';
  import User from '@/structure/user';
  import user from '@/structure/user';
  import OtpUtils from '@/utils/otp';
  import UserUtils from '@/utils/user';
  import {Component, Vue} from 'vue-property-decorator';

  interface OauthBind {
    key: string;
    label: string;
    bound: boolean;
    api: AbstractOauthControlPanelApi;
  }

  @Component
  export default class Page extends Vue {
    public securityProgress: any = {
      value: 0,
      status: 'exception',
      displayText: '不安全'
    };
    public info: User = new User();
    public list: Position[] = [];
    public changePasswordDialog: DialogInfo = new DialogInfo();
    public otpDialog: DialogInfo = new DialogInfo();
    public qrBarcode: string = '';
    public secretKey: string = '';
    public otp: string = '';
    public password: PasswordInfo = new PasswordInfo();
    public iphoneDownload: string = 'https://apps.apple.com/cn/app/microsoft-authenticator/id983156458';
    public androidDownload: string = 'https://sj.qq.com/myapp/detail.htm?apkName=com.azure.authenticator';
    public oauthBinds: OauthBind[] = [];

    public created() {
      this.info = UserUtils.getUser();

      let securityProgress = 0;
      if (this.info.email) {
        securityProgress++;
      }
      if (this.info.phone) {
        securityProgress++;
      }
      if (this.info.enableTwoFactorAuthentication) {
        securityProgress++;
      }
      this.securityProgress.value = Math.floor(securityProgress * 100 / 3);

      if (this.securityProgress.value > 80) {
        this.securityProgress.status = 'success';
        this.securityProgress.displayText = '高';
      } else if (this.securityProgress.value > 60) {
        this.securityProgress.status = 'warning';
        this.securityProgress.displayText = '中';
      } else {
        this.securityProgress.status = 'exception';
        this.securityProgress.displayText = '低';
      }

      ControlPanelApi.getPositions().then((res) => this.list = res);
      WxCpControlPanelApi.bindStatus().then((res) => {
        this.oauthBinds.push({
          key: 'wxCp',
          label: '企业微信',
          bound: res,
          api: WxCpControlPanelApi
        });
      });
      DingTalkControlPanelApi.bindStatus().then((res) => {
        this.oauthBinds.push({
          key: 'dingTalk',
          label: '钉钉',
          bound: res,
          api: DingTalkControlPanelApi
        });
      });
    }

    public formatPhone(phone: string): string {
      return phone.substr(0, 3) + '****' + phone.substr(7);
    }

    public formatEmail(email: string): string {
      return email.substr(0, 1) + '******' + email.substr(email.indexOf('@'));
    }

    // 修改头像相关函数 -- start
    public getUploadAvatarUrl(): string {
      return process.env.VUE_APP_API_URL + '/user/user/controlPanel/avatar';
    }

    public getHeaders(): object {
      const token = UserUtils.getAccessToken();
      return {
        Authorization: token ? token : '' as string
      };
    }

    public handleUploaded(res: Result<user>): void {
      if (res.status && res.data !== undefined) {
        UserUtils.setUser(res.data);
        this.info = res.data;
        AvatarModule.change(this.info.avatar);
        this.$message.success('修改头像成功');
      } else {
        this.$message.error(res.message);
      }
    }

    public deleteAvatar(): void {
      ControlPanelApi.deleteAvatar().then((res) => {
        UserUtils.setUser(res);
        this.info = res;
        AvatarModule.change(this.info.avatar);
        this.$message.success('删除头像成功');
      });
    }

    // 修改头像相关函数 -- end

    // 修改密码相关函数 -- start
    public changePassword() {
      this.changePasswordDialog.show = true;
      this.changePasswordDialog.submitting = false;
      this.password.newPassword = '';
      this.password.oldPassword = '';
    }

    public cancelChangePassword() {
      this.changePasswordDialog.show = false;
      this.changePasswordDialog.submitting = false;
    }

    public submitChangePassword() {
      if (this.changePasswordDialog.submitting) {
        return;
      }

      this.changePasswordDialog.submitting = true;
      ControlPanelApi.updatePassword(this.password).then(() => {
        this.$message.success('修改成功');
        this.changePasswordDialog.show = false;
        UserUtils.clean();
        location.reload();
      });
    }

    // 修改密码相关函数 -- end

    // 双因子验证相关函数 -- start
    public cancelTwoFactorAuthentication() {
      this.otpDialog.show = false;
      this.otpDialog.submitting = false;
    }

    public getTwoFactorAuthenticationBindInfo() {
      ControlPanelApi.getTwoFactorAuthenticationBindInfo().then((res) => {
        this.otpDialog.show = true;
        this.secretKey = res.secretKey;
        this.qrBarcode = res.qrBarcode;
        this.otp = '';
      });
    }

    public enableTwoFactorAuthentication() {
      if (this.otp.length !== 6) {
        this.$message.error('动态密码长度错误');
        return;
      }
      if (this.otpDialog.submitting) {
        return;
      }

      this.otpDialog.submitting = true;
      ControlPanelApi.enableTwoFactorAuthentication(this.secretKey, this.otp).then((res) => {
        UserUtils.set(res);
        this.info = UserUtils.getUser();
        this.cancelTwoFactorAuthentication();
        this.$message.success('绑定成功');
      }).catch(({errorCode, message}) => {
        this.otpDialog.submitting = false;
        if (errorCode >= 900 && errorCode < 1000) {
          this.$message.error(message);
        }
      });
    }

    public disableTwoFactorAuthentication() {
      OtpUtils.enableOtp().then((otp) => {
        ControlPanelApi.disableTwoFactorAuthentication(otp).then((res) => {
          UserUtils.set(res);
          this.info = UserUtils.getUser();
          this.$message.success('解绑成功');
        }).catch(({errorCode, message}) => {
          if (errorCode >= 900 && errorCode < 1000) {
            this.$message.error(message);
          }
        });
      });
    }

    // 双因子验证相关函数 -- end

    // oauth -- start
    public unBind(data: OauthBind): void {
      const label = data.label;

      this.$confirm(`是否要解除${label}绑定？`, `解除${label}绑定`, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        data.api.unbind().then(() => {
          data.bound = false;
          this.$message.success(`解除${label}绑定成功!`);
        });
      }).catch();
    }

    // oauth -- end
  }
</script>
<style lang="scss" scoped>
    .oauth {
        display: inline-block;
        margin-right: 10px;

        &:last-child {
            margin-right: 0;
        }

        .icon {

        }
    }

    .position {
        margin-right: 10px;

        &:last-child {
            margin-right: 0;
        }
    }

    .qrcode-box {
        width: 100%;
        display: inline-block;

        .qrcode {
            text-align: center;
        }

        span {
            width: 100%;
            text-align: center;
            display: inline-block;
        }
    }

    .security-progress {
        width: 200px;
        display: inline-block;
    }

    .controlPanel-box {
        margin: 20px;
    }

    .controlPanel-bg {
        background-color: #fff;
        padding: 20px;
        border: 1px solid #e3e2e2;
    }

    .basic-info {
        & > div {
            display: inline-block;
        }

        & > p {
            display: inline-block;
            height: 80px;
            line-height: 80px;
            margin: 0;
            padding-left: 20px;

            i {
                color: #999;
            }
        }
    }

    .avatar-button {
        display: inline-block;
    }

    .upload-avatar-box {
        width: 80px;
        margin-top: 10px;
        text-align: center;
    }

    .table-title {
        margin: 20px 0;
        padding-left: 10px;
        border-left: 5px solid #3b6cbe;
    }
</style>
